#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;
/*
信号：
    信号是一种软件中断，用于通知进程发生了某种事件
    信号是异步的，进程不需要等待信号的处理，当信号到达时，进程会被中断，执行信号处理函数
    (​​信号是异步事件通过内核调度机制实现同步化处理的过程)
    信号是进程间通信的一种方式

概念：
1、信号是软件模拟硬件的中断功能，信号是软件实现的，中断是硬件实现的
   中断：停止当前正在执行的事情，去做另一件事情
2、信号是linux内核实现的，没有内核就没有信号的概念
3、用户可以给进程发信号：例如键入ctrl+c
   内核可以向进程发送信号：例如SIGPIPE
   一个进程可以给另一个进程发送信号，需要通过相关函数来完成
4、信号通信是属于异步通信工作


信号的种类：
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
 11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
 16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
 21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
 26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
 31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
 38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
 43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
 58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
 63) SIGRTMAX-1  64) SIGRTMAX

1、一共可以发射62个信号，前32个是稳定信号，后面是不稳定信号
2、常用的信号
SIGHUP：当进程所在的终端被关闭后，终端会给运行在当前终端的每个进程发送该信号，默认结束进程
SIGINT：中断信号，当用户键入ctrl + c时发射出来
SIGQUIT：退出信号，当用户键入ctrl + /是发送，退出进程
SIGKILL：杀死指定的进程
SIGSEGV：当指针出现越界访问时，会发射，表示段错误
SIGPIPE：当管道破裂时会发送该信号
SIGALRM：当定时器超时后，会发送该信号
SIGSTOP：暂停进程，当用户键入ctrl+z时发射
SIGTSTP：也是暂停进程
SIGTSTP、SIGUSR2 ：留给用户自定义的信号，没有默认操作
SIGCHLD：当子进程退出后，会向父进程发送该信号
3、有两个特殊信号：SIGKILL和SIGSTOP，这两个信号既不能被捕获，也不能被忽略
4> 对应信号的处理方式有三种：捕获(自定义)、忽略、默认
5> 对信号的处理函数：signal
 #include <signal.h>

 typedef void (*sighandler_t)(int);
 sighandler_t signal(int signum, sighandler_t handler);
    功能：将信号与信号处理方式绑定到一起
    参数1：要处理的信号
    参数2：处理方式
    SIG_IGN：忽略
    SIG_DFL：默认，一般信号的默认操作都是杀死进程
    typedef void (*sighandler_t)(int)：用户自定义的函数
    返回值：成功返回处理方式的起始地址，失败返回SIG_ERR并置位错误码
*/
// 自定义信号处理函数

void handler(int signum)
{
    if (signum == SIGINT)
        cout << "ctl+c被触发" << endl;
}

int main(int argc, const char *argv[])
{
    // 将ctl+c(中断信号)忽视
    // if (signal(SIGINT, SIG_IGN) == SIG_ERR)
    // {
    //     perror("signal error");
    //     return -1;
    // }

    // 自定义
    // if (signal(SIGINT, handler) == SIG_ERR)
    // {
    //     perror("signal error");
    //     return -1;
    // }

    // 默认(一般是杀死进程)
    if (signal(SIGINT, SIG_DFL) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }

    // 别忘记SIGKILL和SIGSTOP，这两个信号既不能被捕获，也不能被忽略哦

    while (1)
    {
        cout << "hello world" << endl;
        sleep(1.5);
    }

    return 0;
}
